package com.softserveinc.lahire.communicator;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.sql.Time;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.sql.PooledConnection;

import com.softserveinc.lahire.builders.HTTPWorker;
import com.softserveinc.lahire.configurator.Configurator;

public class Communicator implements Runnable {

	private static Communicator instance;
	private ServerSocket serverSocket;
	private ThreadPoolExecutor threadPool;
	private BlockingQueue queue;
	private RejectedExecutionHandler ree;

	private Communicator() throws IOException {

	}

	public void run() {

		try {
			while (!serverSocket.isClosed()) {
				Socket clientSocket = serverSocket.accept();

				threadPool.execute(new HTTPWorker(clientSocket));
				
				/*Thread first = new HTTPWorker(clientSocket);
				first.start();*/

			}
		} catch (IOException e) {
			System.out.println("Server stoped listening on port");

		}
	}

	public String getHostPort() {
		return serverSocket.getLocalSocketAddress().toString();
	}

	public void stopMe() throws IOException {
		threadPool.shutdownNow();
		serverSocket.close();
	}

	public void startMe() throws IOException {
		serverSocket = new ServerSocket(Integer.parseInt(Configurator
				.getInstance().getByTag("tcpPort")), 500,
				InetAddress.getByName(Configurator.getInstance().getByTag(
						"IPAddr")));
		System.out.println("Server started listening on TCP port: "
				+ serverSocket.getLocalPort());

		queue = new ArrayBlockingQueue<HTTPWorker>(
				Integer.parseInt(Configurator.getInstance().getByTag(
						"connectionsMax")) * 2);
			ree = new RejectedExecutionHandler() {

			public void rejectedExecution(Runnable r,
					ThreadPoolExecutor executor) {

			}
		};

		threadPool = new ThreadPoolExecutor(Integer.parseInt(Configurator
				.getInstance().getByTag("threadsMax")),
				Integer.parseInt(Configurator.getInstance().getByTag(
						"connectionsMax")), 20, TimeUnit.SECONDS, queue, ree);

	}

	// Create a singleton instance for Communicator

	public static synchronized Communicator getInstance() {
		if (instance == null) {
			try {
				instance = new Communicator();
			} catch (IOException e) {
				System.out.println("Port already used");
			}
		}
		return instance;

	}

}
